package tools

import (
	"archive/zip"
	"bufio"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"
)

// FileExist 这里需要判断错误类型, 有可能是权限不足, 无法进入目录不知道目录类型
func FileExist(filePath string) (bool, error) {
	_, err := os.Stat(filePath)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) == true {
		return false, nil
	}
	return false, err
}

// IsDir 判断是否为目录
func IsDir(path string) (bool, error) {
	// 获取文件或目录的信息
	fileInfo, err := os.Stat(path)
	if err != nil {
		return false, err
	}
	// 判断是否是目录
	if fileInfo.IsDir() {
		return true, nil
	} else {
		return false, nil
	}
}

// CopyFile 复制文件
func CopyFile(srcFile, dstFile string) (err error) {
	// 打开源文件
	source, err := os.Open(srcFile)
	if err != nil {
		fmt.Println("无法打开源文件:", err)
		return
	}
	defer source.Close()
	// 创建或截断目标文件
	destination, err := os.Create(dstFile)
	if err != nil {
		fmt.Println("无法创建目标文件:", err)
		return
	}
	defer destination.Close()

	// 使用缓冲区进行文件复制
	reader := bufio.NewReader(source)
	writer := bufio.NewWriter(destination)

	_, err = io.Copy(writer, reader)
	if err != nil {
		fmt.Println("文件复制失败:", err)
		return
	}

	// 确保所有内容都被写入磁盘
	err = writer.Flush()
	if err != nil {
		fmt.Println("刷新缓冲区时出错:", err)
		return
	}
	return nil
}

// CreateDir 创建目录
func CreateDir(dirName string) {
	if dirName == "" {
		return
	}
	err := os.MkdirAll(dirName, 0755)
	if err != nil {
		//log.Fatal(err)
		fmt.Println("目录创建失败!", dirName, ":", err)
	}
	//fmt.Println("目录创建成功", dirName)
}

// ReadFileContent 读取文件内容
func ReadFileContent(filePath string) (contentStr string, err error) {
	contentByte, err := os.ReadFile(filePath)
	if err != nil {
		return
	}
	contentStr = string(contentByte)
	return
}

var logLock sync.Mutex

func WriteStringToLog(content string, fileName string, mode string) (err error) {
	logLock.Lock()
	defer logLock.Unlock()
	if fileName == "" {
		fileName = "common.log"
	}
	fileName = "./runtime/logs/" + time.Now().Format("20060102") + "-" + fileName
	CreateDir(filepath.Dir(fileName))
	var flag int
	if mode == "" || mode == "a" {
		flag = os.O_WRONLY | os.O_CREATE | os.O_APPEND
	} else {
		flag = os.O_WRONLY | os.O_CREATE
	}
	logFile, err := os.OpenFile(fileName, flag, 0644)
	if err != nil {
		return
	}
	_, err = logFile.Write([]byte(content + "\n"))
	if err != nil {
		return
	}
	err = logFile.Close()
	if err != nil {
		return
	}
	return nil
}

func WriteStringToFile(content string, fileName string, mode string) (err error) {
	logLock.Lock()
	defer logLock.Unlock()
	if fileName == "" {
		fileName = "tmp_file.log"
	}
	CreateDir(filepath.Dir(fileName))
	var flag int
	if mode == "" || mode == "a" {
		flag = os.O_WRONLY | os.O_CREATE | os.O_APPEND
	} else {
		flag = os.O_WRONLY | os.O_CREATE
	}
	logFile, err := os.OpenFile(fileName, flag, 0644)
	if err != nil {
		return
	}
	_, err = logFile.Write([]byte(content + "\n"))
	if err != nil {
		return
	}
	err = logFile.Close()
	if err != nil {
		return
	}
	return nil
}

// ZipCompress 压缩目录文件
func ZipCompress(source, target string) error {
	// 创建 .zip 文件
	zipFile, err := os.Create(target)
	if err != nil {
		return err
	}
	defer zipFile.Close()

	// 创建新的 zip writer
	zipWriter := zip.NewWriter(zipFile)
	defer zipWriter.Close()

	// 遍历源目录
	err = filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		header, err := zip.FileInfoHeader(info)
		if err != nil {
			return err
		}

		// 设置压缩方法
		header.Method = zip.Deflate

		// 相对路径
		header.Name, err = filepath.Rel(filepath.Dir(source), path)
		if err != nil {
			return err
		}
		if info.IsDir() {
			header.Name += "/" // 对于目录结尾加上斜杠
		} else {
			header.Name = strings.TrimPrefix(header.Name, "/")
		}

		// 创建文件头
		writer, err := zipWriter.CreateHeader(header)
		if err != nil {
			return err
		}

		// 如果不是目录，则复制文件内容
		if !info.IsDir() {
			file, err := os.Open(path)
			if err != nil {
				return err
			}
			defer file.Close()
			_, err = io.Copy(writer, file)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		return err
	}
	return nil
}
